#prova prova prova
class IngredienteIllegale < Exception
end

class IngredienteSconosciuto < Exception
end

class RicettaIllegale < Exception
end

class Ingredienti


include Comparable

    @@elenco=[]
    @@sempre_con={}
    @@mai_con={}
 

  def Ingredienti.aggiungi(elenco,sempre_con,mai_con)
    if @@elenco.include?(elenco)
      raise IngredienteIllegale
    else
    @@elenco << elenco
    @@sempre_con[elenco]=sempre_con
    @@mai_con[elenco]=mai_con
    end
  end

  def Ingredienti.sempre_con(x)
    raise IngredienteSconosciuto if !@@elenco.include?(x)
    return @@sempre_con[x]
  end

  def Ingredienti.mai_con(x)
    raise IngredienteSconosciuto if !@@elenco.include?(x)
    return @@mai_con[x]
  end
  def Ingredienti.elenco()
    return @@elenco.sort!
  end
end

class Ricetta
  attr_accessor :nome, :ingr


  def initialize(n,i)
    i.each { |x| raise IngredienteSconosciuto unless Ingredienti.elenco.include?(x)}
    i.each{|a| raise RicettaIllegale if Ingredienti.mai_con(a)&i!=[] }
    @nome=n
    @ingr=i
  end

  def completa?
    @ingr.each{|b| return false if Ingredienti.sempre_con(b)-@ingr!=[]}
    return true
  end

  def aggiungi_ingrediente(q)
    raise RicettaIllegale if Ingredienti.mai_con(q)&@ingr!=[] ||  @ingr.find{|c| (Ingredienti.mai_con(c)).include?(q)}
    @ingr << q
  end

  def to_s
    t="#{@nome} --> "
    @ingr.each{|x| t+="#{x}: "}
    return t
  end

  def Ricetta.crea(nome,ingr)
    messi=[]
    da_mettere=[ingr]
    while (!da_mettere.empty?)
    i=da_mettere.pop
    messi<<i
    Ingredienti.sempre_con(i).each{|x| da_mettere<<x unless  da_mettere.include?(x) ||  messi.include?(x)}
    end
    return Ricetta.new(nome,messi)
  rescue RicettaIllegale, IngredienteSconosciuto
    return nil


  end

end

class Menu

  def initialize()
    @menu=[]
  end

  def aggiungi_ricetta(r)
    return false if @menu.any? {|o| o.nome==r.nome} #@menu.include?(r)
    return false if !r.completa?
    @menu << r
    return true
  end

  def ricette_possibili(rp)
    return @menu.find_all { |x| x.ingr-rp==[] }
  end

  def to_s
    t="menu\n"
    @menu.each {|x| t+="#{x}\n"}
    return t
  end
end

def main

  puts "--------------- definizione ingredienti ---------------"
  Ingredienti.aggiungi("pomodoro",[],[])
  Ingredienti.aggiungi("cipolle",["olio"],["funghi","origano"])
  Ingredienti.aggiungi("piselli",[],[])
  Ingredienti.aggiungi("patate",[],[])
  Ingredienti.aggiungi("peperoni",[],[])
  Ingredienti.aggiungi("prosciutto",[],[])
  Ingredienti.aggiungi("pancetta",[],[])
  Ingredienti.aggiungi("funghi",[],[])
  Ingredienti.aggiungi("olio",[],[])
  Ingredienti.aggiungi("aglio",[],["burro"])
  Ingredienti.aggiungi("sale",[],[])
  Ingredienti.aggiungi("pepe",[],["zafferano"])
  Ingredienti.aggiungi("zafferano",[],["pepe"])
  Ingredienti.aggiungi("uova",[],[])
  Ingredienti.aggiungi("penne",[],["riso", "spaghetti"])
  Ingredienti.aggiungi("burro",[],["margarina"])
  Ingredienti.aggiungi("basilico",[],[])
  Ingredienti.aggiungi("formaggio",[],[])
  Ingredienti.aggiungi("margarina",[],["olio"])
  Ingredienti.aggiungi("spaghetti",["sale","olio"],["riso"])
  Ingredienti.aggiungi("riso",["sale"],["spaghetti"])

  puts Ingredienti.elenco


  puts "--- riso cantonese ---"
  begin
    ric = Ricetta.new("riso cantonese",["riso","sale","cianuro"])
    puts "Errore! doveva essere lanciata un'eccezione IngredienteSconosciuto"
    return
  rescue IngredienteSconosciuto
    puts "Eccezione OK"
  end

  ric = Ricetta.new("riso cantonese",["riso","piselli","prosciutto","uova"])
  puts ric.completa?
  ric.aggiungi_ingrediente("sale")
  puts ric.completa?

  menu = Menu.new()
  puts menu.aggiungi_ricetta(ric)


  puts "--- spaghetti carbonara ---"
  begin
    ric = Ricetta.new("spaghetti carbonara",["spaghetti","riso"])
    puts "Errore! doveva essere lanciata un'eccezione RicettaIllegale"
    return
  rescue RicettaIllegale
    puts "Eccezione OK 1"
  end

  begin
    ric = Ricetta.new("spaghetti carbonara",["spaghetti","sale", "penne"])
    puts "Errore! doveva essere lanciata un'eccezione RicettaIllegale"
    return
  rescue RicettaIllegale
    puts "Eccezione OK 2"
  end

  begin
    ric = Ricetta.new("spaghetti carbonara",["penne","sale", "spaghetti"])
    puts "Errore! doveva essere lanciata un'eccezione RicettaIllegale"
    return
  rescue RicettaIllegale
    puts "Eccezione OK 3"
  end

  ric = Ricetta.new("spaghetti carbonara",["spaghetti","uova","pepe","olio",
    "formaggio"])
  begin
    ric.aggiungi_ingrediente("zafferano")
    puts "Errore! doveva essere lanciata un'eccezione RicettaIllegale"
    return
  rescue RicettaIllegale
    puts "Eccezione OK 4"
  end

  begin
    ric.aggiungi_ingrediente("margarina")
    puts "Errore! doveva essere lanciata un'eccezione RicettaIllegale"
    return
  rescue RicettaIllegale
    puts "Eccezione OK 5"
  end


  # rifiutata perche' manca il sale
  puts menu.aggiungi_ricetta(ric)

  begin
    ric.aggiungi_ingrediente("arsenico")
    puts "Errore! doveva essere lanciata un'eccezione IngredienteSconosciuto"
    return
  rescue IngredienteSconosciuto
    puts "Eccezione OK 6"
  end

  ric.aggiungi_ingrediente("pancetta");
  ric.aggiungi_ingrediente("sale");
  puts menu.aggiungi_ricetta(ric)

  ric = Ricetta.new("spaghetti carbonara",["spaghetti","uova","olio","sale"])
  # rifiutata perche il nome e' gia' nel menu
  puts menu.aggiungi_ricetta(ric)

  puts menu

  puts "--- altre ricette ---"
  ric = Ricetta.new("spag. pesto",["spaghetti","olio","sale","basilico",
      "formaggio"])
  puts menu.aggiungi_ricetta(ric)
  ric = Ricetta.new("spag. pomodoro",["spaghetti","olio","sale","basilico",
      "pomodoro"])
  puts menu.aggiungi_ricetta(ric)
  ric = Ricetta.new("spag. aglio",["spaghetti","olio","sale","aglio"])
  puts menu.aggiungi_ricetta(ric)
  ric = Ricetta.new("omelette",["uova","olio","sale","basilico","pepe"])
  puts menu.aggiungi_ricetta(ric)
  ric = Ricetta.new("ratatouille",["olio","sale","patate","piselli","peperoni",
    "funghi"])
  puts menu.aggiungi_ricetta(ric)
  ric = Ricetta.new("risotto",["riso","cipolle","olio","zafferano","sale"])
  puts menu.aggiungi_ricetta(ric)
  ric = Ricetta.new("riso funghi",["riso","olio","funghi","sale"])
  puts menu.aggiungi_ricetta(ric)
  ric = Ricetta.new("patate lesse",["patate","olio","sale"])
  puts menu.aggiungi_ricetta(ric)
  puts menu

  puts "--------- test ricette possibili ----------"
  puts "test1"
  ris =  menu.ricette_possibili(["riso","spaghetti","sale","olio","cipolle",
    "patate","aglio","funghi"])
  puts ris.size>0 ? ris :  "Nessuna ricetta"
  puts "test2"
  ris =  menu.ricette_possibili(["riso","sale","olio","cipolle",
    "piselli","aglio","uova","basilico","pepe","zafferano"])
  puts ris.size>0 ? ris :  "Nessuna ricetta"
  puts "test3"
  ris = menu.ricette_possibili(["riso","spaghetti","sale","olio","peperoni",
      "formaggio"])
  puts ris.size>0 ? ris :  "Nessuna ricetta"

  puts "------ test crea ricetta ------"
  ris = Ricetta.crea("spaghetti semplici", "spaghetti")
  puts  ris ? ris : "Nessuna ricetta possible"

  Ingredienti.aggiungi("carciofi",["cipolle", "carote"],[])
  Ingredienti.aggiungi("carote",["cipolle", "olio", "piselli"],["pomodoro"])

  ris = Ricetta.crea("carciofi semplici", "carciofi")
  puts  ris ? ris : "Nessuna ricetta possible"

  Ingredienti.aggiungi("mais",["pomodoro", "carote"],[])
  ris = Ricetta.crea("impossibile", "mais")
  puts  ris ? ris : "Nessuna ricetta possible"

  Ingredienti.aggiungi("zucchini",["sedano"],[])
  ris = Ricetta.crea("impossibile", "zucchini")
  puts  ris ? ris : "Nessuna ricetta possible"

  puts "----------- fine test ------------"
end

main
